package com.jp.fm.servlet;

import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.jp.fm.EasyMockParent;
import com.jp.fm.dao.AccountDao;
import com.jp.fm.dao.BudgetDao;
import com.jp.fm.dao.CategoryDao;
import com.jp.fm.data.Budget;
import com.jp.fm.data.Category;
import com.jp.fm.service.BudgetService;
import com.jp.fm.service.CategoryService;
import com.jp.fm.service.PageService;
import com.jp.fm.service.TransactionService;

public class ShowTrendsTest extends EasyMockParent {

	private ShowTrends servlet = null;

	private HttpServletRequest mockRequest = null;
	private HttpServletResponse mockResponse = null;
	private AccountDao mockAccountDao = null;
	private CategoryDao mockCategoryDao = null;
	private BudgetDao mockBudgetDao = null;
	private TransactionService mockTransactionService = null;
	private CategoryService mockCategoryService = null;
	private BudgetService mockBudgetService = null;
	private PageService mockPageService = null;
	private RequestDispatcher mockRequestDispatcher = null;

	@Before
	public void setUp() throws Exception {
		super.setUp();

		servlet = new ShowTrends();
	}

	@After
	public void tearDown() throws Exception {
		super.tearDown();
	}

	@Test
	public final void testComposeBudgetChartData() {
		servlet.setAccountDao(mockAccountDao);
		servlet.setBudgetDao(mockBudgetDao);
		servlet.setCategoryDao(mockCategoryDao);
		servlet.setBudgetService(mockBudgetService);
		servlet.setCategoryService(mockCategoryService);
		servlet.setPageService(mockPageService);
		servlet.setTransactionService(mockTransactionService);

		List<Budget> budgets = new ArrayList<Budget>();
		Budget budget = new Budget(null, new Date(), Float.valueOf("100.88"),
				null, null, new Category(null, "testCategory"));
		budget.setCurrentAmount(Float.valueOf("5.99"));
		budgets.add(budget);

		expect(mockRequest.getParameter("budgetSelect")).andReturn(null);
		mockRequest.setAttribute(eq("budgetSelect"), anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("budgetTimeFrameMap"),
				anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("budgetSelectDate"), anyObject(Date.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("budgetEndDate"), anyObject(Date.class));
		EasyMock.expectLastCall();
		expect(
				mockBudgetService.findBudgetList(anyObject(Date.class),
						anyObject(Date.class), anyObject(List.class)))
				.andReturn(budgets);

		mockRequest.setAttribute(eq("budgetCategoryStr"),
				anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest
				.setAttribute(eq("budgetAmountStr"), anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("budgetCatAmountStr"),
				anyObject(String.class));
		EasyMock.expectLastCall();

		replayMocks();

		servlet.composeBudgetChartData(mockRequest);
	}

	@Test
	public final void testComposeAccountBalancesChartData() {

		servlet.setAccountDao(mockAccountDao);
		servlet.setBudgetDao(mockBudgetDao);
		servlet.setCategoryDao(mockCategoryDao);
		servlet.setBudgetService(mockBudgetService);
		servlet.setCategoryService(mockCategoryService);
		servlet.setPageService(mockPageService);
		servlet.setTransactionService(mockTransactionService);

		mockPageService.composeAccountBalancesOverTime(eq(mockRequest),
				anyInt());
		EasyMock.expectLastCall();

		replayMocks();

		servlet.composeAccountBalancesChartData(mockRequest);
	}

	@Test
	public final void testComposeTopCategoriesChartData() {

		servlet.setAccountDao(mockAccountDao);
		servlet.setBudgetDao(mockBudgetDao);
		servlet.setCategoryDao(mockCategoryDao);
		servlet.setBudgetService(mockBudgetService);
		servlet.setCategoryService(mockCategoryService);
		servlet.setPageService(mockPageService);
		servlet.setTransactionService(mockTransactionService);

		Map<Float, Category> map = new HashMap<Float, Category>();
		map.put(Float.valueOf("100.00"), new Category(null, "test"));

		mockRequest.setAttribute(eq("timeFrameMap"), anyObject(Map.class));
		EasyMock.expectLastCall();
		expect(mockRequest.getParameter("categoryPieSelect")).andReturn(null);
		mockRequest.setAttribute(eq("categoryPieTitle"),
				anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("categoryPieSelect"),
				anyObject(String.class));
		EasyMock.expectLastCall();
		expect(
				mockCategoryService.getTopCategoriesOverTimeFrame(
						anyObject(Date.class), anyObject(Date.class)))
				.andReturn(map);
		mockRequest.setAttribute(eq("topCatsStartDate"),
				anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("topCatsEndDate"), anyObject(String.class));
		EasyMock.expectLastCall();
		mockRequest.setAttribute(eq("topCategories"), anyObject(Map.class));
		EasyMock.expectLastCall();

		replayMocks();

		servlet.composeTopCategoriesChartData(mockRequest);
	}

	@Test
	public final void testDoPostSuccess() throws ServletException, IOException {

		Class[] args = { HttpServletRequest.class, HttpServletResponse.class };

		ShowTrends partialMockServlet = (ShowTrends) createPartialMock(
				ShowTrends.class, "doPost", args, false);

		partialMockServlet.setAccountDao(mockAccountDao);
		partialMockServlet.setBudgetDao(mockBudgetDao);
		partialMockServlet.setCategoryDao(mockCategoryDao);
		partialMockServlet.setBudgetService(mockBudgetService);
		partialMockServlet.setCategoryService(mockCategoryService);
		partialMockServlet.setPageService(mockPageService);
		partialMockServlet.setTransactionService(mockTransactionService);

		mockPageService.composeRequestLeftNav(mockRequest);
		EasyMock.expectLastCall();
		partialMockServlet.composeTopCategoriesChartData(mockRequest);
		EasyMock.expectLastCall();
		partialMockServlet.composeAccountBalancesChartData(mockRequest);
		EasyMock.expectLastCall();
		partialMockServlet.composeBudgetChartData(mockRequest);
		EasyMock.expectLastCall();

		expect(mockRequest.getRequestDispatcher(anyObject(String.class)))
				.andReturn(mockRequestDispatcher);
		mockRequestDispatcher.forward(mockRequest, mockResponse);
		EasyMock.expectLastCall();

		replayMocks();
		EasyMock.replay(partialMockServlet);

		partialMockServlet.doPost(mockRequest, mockResponse);

		EasyMock.verify(partialMockServlet);
	}

}
